

package com.googlecode.flac4j.format.frame.sub;


import com.googlecode.jinahya.io.BitInput;
import com.googlecode.jinahya.io.BitOutput;

import java.io.IOException;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;


/**
 *
 * @author Jin Kwon <jinahya at gmail.com>
 */
@XmlTransient
@XmlType(propOrder = {"parameter", "sampleSize", "sampleCount"})
public class AbstractPartition extends Partition {


    /**
     * Creates a new instance.
     *
     * @param parameterLength parameter length in bits.
     * @param sampleSizeLength sampleSize length in bits.
     */
    public AbstractPartition(final int parameterLength,
                             final int sampleSizeLength) {
        super();

        if (parameterLength < 1) {
            throw new IllegalArgumentException(
                "parameterLength(" + parameterLength + ") < 1");
        }

        if (parameterLength >= 32) {
            throw new IllegalArgumentException(
                "parameterLength(" + parameterLength + ") >= 32");
        }

        if (sampleSizeLength < 1) {
            throw new IllegalArgumentException(
                "sampleSizeLength(" + sampleSizeLength + ") < 1");
        }

        if (sampleSizeLength >= 32) {
            throw new IllegalArgumentException(
                "sampleSizeLength(" + sampleSizeLength + ") >= 32");
        }

        this.parameterLength = parameterLength;
        maximumParameter = (int) Math.pow(2, this.parameterLength) - 1;

        this.sampleSizeLength = sampleSizeLength;
    }


    @Override
    public void read(final BitInput input) throws IOException {

        parameter = input.readUnsignedInt(parameterLength);

        if (parameter == maximumParameter) {
            sampleSize = input.readUnsignedInt(sampleSizeLength);
        }

        if (rice.getOrder() == 0) {
        }
    }


    @Override
    public void write(final BitOutput output) throws IOException {

        output.writeUnsignedInt(parameterLength, parameter);

        if (parameter == maximumParameter) {
            output.writeUnsignedInt(sampleSizeLength, sampleSize);
        }
    }


    // --------------------------------------------------------------- parameter
    /**
     * Returns parameter.
     *
     * @return parameter
     */
    public final int getParameter() {
        return parameter;
    }


    /**
     * Sets parameter.
     *
     * @param parameter parameter
     */
    public final void setParameter(final int parameter) {

        if (parameter >> parameterLength != 0) {
            throw new IllegalArgumentException(
                "parameter(" + parameter + ") >> parameterLength("
                + parameterLength + ") != 0");
        }

        this.parameter = parameter;
    }


    // -------------------------------------------------------------- sampleSize
    /**
     * Returns bits per sample.
     *
     * @return bits per sample
     */
    public final int getSampleSize() {
        return sampleSize;
    }


    /**
     * Sets bits per sample.
     *
     * @param sampleSize bits per sample
     */
    public final void setSampleSize(final int sampleSize) {

        if (sampleSize >> sampleSizeLength != 0) {
            throw new IllegalArgumentException(
                "sampleSize(" + sampleSize + ") >> sampleSizeLength("
                + sampleSizeLength + ") != 0");
        }

        if (sampleSize > 0) {
            parameter = maximumParameter;
        }

        this.sampleSize = sampleSize;
    }


    /**
     * Returns the number of samples.
     * 
     * @return number of samples
     */
    public int getSampleCount() {
        return sampleCount;
    }


    /**
     * Sets the number of samples.
     *
     * @param sampleCount number of samples
     */
    public void setSampleCount(final int sampleCount) {

        this.sampleCount = sampleCount;
    }


    /** parameter length in bits. */
    @XmlTransient
    private final int parameterLength;


    /** maximum parameter. */
    @XmlTransient
    private final int maximumParameter;


    /** sample size length in bits. */
    @XmlTransient
    private final int sampleSizeLength;


    /** parameter. */
    @XmlElement(required = true)
    private int parameter;


    /** bits per sample. */
    @XmlElement(required = true)
    private int sampleSize = 0;


    /** number of samples. */
    @XmlElement(required = true)
    private int sampleCount;


}

